const NotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
const NotificationsProxy = Gio.DBusProxy.makeProxyWrapper(NotificationsIface);
+Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
+
var NotificationDaemon = class extends ServiceImplementation {
constructor() {
super(NotificationsIface, '/org/freedesktop/Notifications');
null, null);
}
- NotifyAsync(params, invocation) {
+ async NotifyAsync(params, invocation) {
+ const pid = await this._getSenderPid(invocation.get_sender());
+ const hints = params[6];
+
+ params[6] = {
+ ...hints,
+ 'sender-pid': new GLib.Variant('u', pid),
+ };
+
this._proxy.NotifyRemote(...params, (res, error) => {
if (this._handleError(invocation, error))
return;
invocation.return_value(new GLib.Variant('(ssss)', res));
});
}
+
+ async _getSenderPid(sender) {
+ const res = await Gio.DBus.session.call(
+ 'org.freedesktop.DBus',
+ '/',
+ 'org.freedesktop.DBus',
+ 'GetConnectionUnixProcessID',
+ new GLib.Variant('(s)', [sender]),
+ new GLib.VariantType('(u)'),
+ Gio.DBusCallFlags.NONE,
+ -1,
+ null);
+ const [pid] = res.deepUnpack();
+ return pid;
+ }
};
const { loadInterfaceXML } = imports.misc.fileUtils;
-// Should really be defined in Gio.js
-const BusIface = loadInterfaceXML('org.freedesktop.DBus');
-var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface);
-function Bus() {
- return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
-}
-
const FdoNotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
var NotificationClosedReason = {
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
this._sources = [];
- this._senderToPid = {};
this._notifications = {};
- this._busProxy = new Bus();
this._nextNotificationId = 1;
//
// If no existing source is found, a new source is created as long as
// pid is provided.
- //
- // Either a pid or ndata.notification is needed to retrieve or
- // create a source.
_getSource(title, pid, ndata, sender) {
if (!pid && !(ndata && ndata.notification))
- return null;
+ throw new Error('Either a pid or ndata.notification is needed');
// We use notification's source for the notifications we still have
// around that are getting replaced because we don't keep sources
this._notifications[id] = ndata;
let sender = invocation.get_sender();
- let pid = this._senderToPid[sender];
+ let pid = hints['sender-pid'];
let source = this._getSource(appName, pid, ndata, sender, null);
-
- if (source) {
- this._notifyForSource(source, ndata);
- return invocation.return_value(GLib.Variant.new('(u)', [id]));
- }
-
- if (replacesId) {
- // There's already a pending call to GetConnectionUnixProcessID,
- // which will see the new notification data when it finishes,
- // so we don't have to do anything.
- return invocation.return_value(GLib.Variant.new('(u)', [id]));
- }
-
- this._busProxy.GetConnectionUnixProcessIDRemote(sender, (result, excp) => {
- // The app may have updated or removed the notification
- ndata = this._notifications[id];
- if (!ndata)
- return;
-
- if (excp) {
- logError(excp, 'Call to GetConnectionUnixProcessID failed');
- return;
- }
-
- [pid] = result;
- source = this._getSource(appName, pid, ndata, sender, null);
-
- this._senderToPid[sender] = pid;
- source.connect('destroy', () => {
- delete this._senderToPid[sender];
- });
- this._notifyForSource(source, ndata);
- });
+ this._notifyForSource(source, ndata);
return invocation.return_value(GLib.Variant.new('(u)', [id]));
}